package com.itheima.reggie.Controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.Pojo.Category;
import com.itheima.reggie.Pojo.Dish;
import com.itheima.reggie.Pojo.DishFlavor;
import com.itheima.reggie.Service.CategoryService;
import com.itheima.reggie.Service.DishFlavorService;
import com.itheima.reggie.Service.DishService;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 菜品管理
 */
@RestController
@RequestMapping("/dish")
public class DishController {
    @Autowired
    private DishService dishService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 添加菜品
     * @param dishDto
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto){
        dishService.saveDish_flavor(dishDto);
        redisTemplate.delete(dishDto.getCategoryId());
        return R.success("菜品添加成功");
    }

    /**
     * 展示分页数据
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(Integer page,Integer pageSize,String name){
//      分页构造器
        Page<Dish> page1 = new Page<>(page,pageSize);
        Page<DishDto> page2 = new Page<>();
//      条件构造器
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
//      添加过滤条件
        wrapper.like(name!=null,Dish::getName,name);
//      添加排序条件
        wrapper.orderByDesc(Dish::getSort);
//      执行分页查询
        dishService.page(page1, wrapper);

//      分页对象拷贝,拷贝时不拷贝records属性，records：即展示在页面的数据的集合，即只拷贝分页的数据，
//      即拷贝分页整体的框架，具体的内容不拷贝;因为这部分内容就是我们想要修改的内容，所以得修改完之后才能用，
//      所以先忽略掉不拷贝它，等修改好这部分内容之后再把它拷贝进来，即这部分内容就是数据
//      参数一：拷贝源 参数二：拷贝到哪去 参数三：忽略掉哪些属性不拷贝
        BeanUtils.copyProperties(page1,page2,"records");
//      获取忽略的records属性(获取数据)
        List<Dish> records = page1.getRecords();

//      item就是遍历出来的每个Dish类型的record，即每一条数据
//      将records由Dish类型处理成DishDto类型
        List<DishDto> list= records.stream().map((item) ->{
//          4、创建一个DishDto类型的对象
            DishDto dishDto = new DishDto();
//          1、分类id
            Long categoryId = item.getCategoryId();
//          2、根据id查询分类对象
            Category category = categoryService.getById(categoryId);
//          3、拿到分类的名称
            if(category!=null){
            String categoryName = category.getName();
//          5、将得到的categoryname的值赋值给dishDto
            dishDto.setCategoryName(categoryName);
            }
//          6、给dishDto拷贝上其他的值
            BeanUtils.copyProperties(item,dishDto);
            return dishDto;
        }).collect(Collectors.toList());

//      给records赋值
        page2.setRecords(list);

        return R.success(page2);
    }

    /**
     * 根据id回显菜品数据(包含口味数据)
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<DishDto> getid(@PathVariable Long id){

        DishDto dishDto = dishService.getdish_flavor(id);

        return R.success(dishDto);
    }


    /**
     * 修改菜品
     * @param dishDto
     * @return
     */
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto){
//      删除相应的缓存
        redisTemplate.delete(dishDto.getCategoryId());

        dishService.updateDish_flavor(dishDto);
        return R.success("菜品修改成功");
    }

    /**
     * 更改菜品状态，起售或停售
     * @param id
     * @param ids
     * @return
     */
    @PostMapping("/status/{id}")
    public R<String> stop(@PathVariable int id, Long[] ids){
        Dish dish = new Dish();
        dish.setStatus(id);

        for (Long deleteid : ids) {
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dish::getId,deleteid);
        dishService.update(dish,queryWrapper);
        }
        return R.success("修改成功");
    }

    /**
     * 删除菜品
     * @param ids
     * @return
     */
    @DeleteMapping
    public R<String> delete(Long[] ids){
        for (Long id : ids) {
        dishService.removeById(id);
        }
        return R.success("删除成功");
    }

    /**
     * 根据分类查询对应分类的菜品信息
     * @param dish
     * @return
     */
//    @GetMapping("/list")
////  用Dish类型接收参数categoryId,只有该类中包含有与参数名称一样的属性,才能用该类型接收该参数
////  这种做法通用性好，可以接收别的参数(名字与类中属性名一样的参数)
//    public R<List<Dish>> select_category(Dish dish){
//        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
////      根据分类id查询菜品
//        queryWrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId());
////      判断菜品是否是起售状态
//        queryWrapper.eq(Dish::getStatus,1);
////      查询
//        List<Dish> list = dishService.list(queryWrapper);
//        return R.success(list);
//
//    }


    /**
     * 根据分类查询对应分类的菜品信息
     * @param dish
     * @return
     */
    @GetMapping("/list")
//  用Dish类型接收参数categoryId,只有该类中包含有与参数名称一样的属性,才能用该类型接收该参数
//  这种做法通用性好，可以接收别的参数(名字与类中属性名一样的参数)
    public R<List<DishDto>> select_category(Dish dish){
        List<DishDto> list2=null;
        list2 = (List<DishDto>) redisTemplate.opsForValue().get(dish.getCategoryId());
        //查询缓存中是否有数据
        if(list2!=null){
        //有的话直接返缓存中数据，
            return R.success(list2);
        }

        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
//      根据分类id查询菜品
        queryWrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId());
//      判断菜品是否是起售状态
        queryWrapper.eq(Dish::getStatus,1);
//      查询该分类菜品的集合
        List<Dish> list = dishService.list(queryWrapper);
//      遍历每个菜品，将dish类型转为dishdto类型，即给每个菜品加上口味数据
         list2 = list.stream().map((item) -> {
//          得到菜品的id
            Long id = item.getId();
            LambdaQueryWrapper<DishFlavor> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(id != null, DishFlavor::getDishId,id);
//          得到当前菜品的口味数据
            List<DishFlavor> list1 = dishFlavorService.list(queryWrapper1);
//          new一个DishDto对象
            DishDto dishDto = new DishDto();
//          拷贝上数据
            BeanUtils.copyProperties(item, dishDto);
//          给口味数据赋值
            dishDto.setFlavors(list1);
            return dishDto;
        }).collect(Collectors.toList());
//       Redis中没有就查数据库，然后将查询出来的数据添加到缓存中
        redisTemplate.opsForValue().set(dish.getCategoryId(),list2,30L, TimeUnit.MINUTES);

        return R.success(list2);

    }
}
